#include <fcntl.h>  // 包含 O_RDWR 等常量
#include <termios.h>  // 包含 termios 结构体
#include <unistd.h>  // 包含 write 函数
#include <stdio.h>  // 包含 perror 函数
#include <string.h>  // 包含 strlen 函数
#include <errno.h>  // 包含 errno 变量
#include <mutex>  // 包含 std::mutex 和 std::lock_guard
#include <iostream>  // 包含 std::cout 和 std::endl
#include <algorithm>  // 包含 std::min 函数
#include <sys/stat.h>  // 新增头文件
#include <atomic>       // 新增
#include <thread>       // 新增
#include <chrono>       // 新增

#include "A010.h"

#if A010_PARSE_LOG_FLAG
#include "log.h"
#endif

char configBuf[20][50]={
    "AT\r\n",
    A010_CONFIG_FPS,
    A010_CONFIG_UNIT,
    A010_CONFIG_DISP_STOP,
    A010_CONFIG_ISP_ON,
    A010_CONFIG_BINN_100,
    //A010_CONFIG_SAVE,
    A010_CONFIG_DISP_STOP,
    "\r\n"
};

// 在全局变量区域添加互斥锁
std::mutex uart_mtx;  // 新增：串口操作互斥锁
std::mutex at_read_mtx;  // 新增：AT指令专用互斥锁

bool A010_ParseFlag = false;
std::atomic<bool> timer_running(false);  // 新增：定时器运行标志
std::mutex timer_mtx;                     // 新增：定时器互斥锁

// 新增发送函数
bool A010_Send(int uart,const char* cmd) {
    std::lock_guard<std::mutex> lock(uart_mtx);  // 加锁保证原子操作
    
    const size_t len = strlen(cmd);
    ssize_t total_sent = 0;
    
    while (total_sent < len) {
        ssize_t n = write(uart, cmd + total_sent, len - total_sent);
        if (n < 0) {
            if (errno == EAGAIN) {  // 非阻塞模式下重试
                usleep(10000);
                continue;
            }
            perror("UART write failed");
            return false;
        }
        total_sent += n;
    }
    return true;
}

std::string A010_Read(int uart,int timeout_ms = 1000) {
    std::lock_guard<std::mutex> lock(at_read_mtx);
    std::string response;
    char buf[UART_RX_MAX_BUFFER_SIZE];
    auto start = std::chrono::steady_clock::now();
    bool has_crlf = false;

    while (std::chrono::steady_clock::now() - start < std::chrono::milliseconds(timeout_ms)) {
        ssize_t n = read(uart, buf, sizeof(buf));
        if (n > 0) {
            response.append(buf, n);
            
            // 新增：检测中间出现的\r\n并记录
            if (!has_crlf && response.find("\r\n") != std::string::npos) {
                has_crlf = true;
            }
            
            // 修改终止条件：仅当出现OK时立即返回
            if (response.find("OK") != std::string::npos) {
                return response.substr(0, response.length());
            }
        } else if (n < 0 && errno != EAGAIN) {
            perror("AT read failed");
            return "AT read failed";
        }
        usleep(100000);
    }

    return "AT read timeout";
}

void A010_TimerInit(int uart)
{   
    std::cout << "A010 Timer Init Success" << std::endl;
    timer_running = true;
    std::thread([](){
        // 初始化时间点
        auto next_wake = std::chrono::steady_clock::now();
        while(timer_running) {
            // 执行定时任务
            {
                std::lock_guard<std::mutex> lock(timer_mtx);
                A010_ParseFlag = !A010_ParseFlag;
                auto now = std::chrono::system_clock::now();
                auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
                    now.time_since_epoch());
                std::cout << "A010 Timer [" << timestamp.count() 
                        << "ms]: " << A010_ParseFlag << std::endl;
            }
            
            // 计算下一个绝对时间点
            next_wake += std::chrono::milliseconds(A010_TRANS_TIME);
            // 等待到绝对时间点
            std::this_thread::sleep_until(next_wake);
        }
    }).detach();
}

#if (A010_PARSE_DEBUG_FLAG | A010_SAVE_WHOLE_FRAME)
FILE* A010_file;
void A010_FileInit(void)
{
    // 新增文件创建逻辑
    mkdir("data", 0777);  // 创建data目录（如果不存在）
    
    // 生成日期时间文件名
    time_t rawtime;
    struct tm *timeinfo;
    char buffer[20];
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S.bin", timeinfo);
    
    // 创建空文件
    std::string filepath = "data/" + std::string(buffer);
    A010_file = fopen(filepath.c_str(), "wb");
}
#endif

static A010_ConfigType A010_config = {0};
A010_ConfigType A010_GetConfig(void)
{
    return A010_config;
}

int A010_Init(int uart)
{
    std::string res;
    memset(&A010_config,0,sizeof(A010_config));

    A010_Send(uart, A010_CONFIG_DISP_STOP);

    A010_Send(uart, A010_CONFIG_BAUD);

    int ret = 0;

    switch (A010_VALUE_BAUD)
    {
    case 0:
        ret = ConfigureSerial(uart,A010_VALUE_BAUD_0);
        A010_config.baud=9600;
        break;
    case 1:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_1);
        A010_config.baud=57600;
        break;
    case 2:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_2);
        A010_config.baud=115200;
        break;
    case 3:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_3);
        A010_config.baud=230400;
        break;
    case 4:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_4);
        A010_config.baud=460800;
        break;
    case 5:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_5);
        A010_config.baud=921600;
        break;
    case 6:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_6);
        A010_config.baud=1000000;
        break;
    case 7:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_7);
        A010_config.baud=2000000;
        break;
    case 8:
        ret = ConfigureSerial(uart, A010_VALUE_BAUD_8);  // 对应头文件中的3000000波特率
        A010_config.baud=3000000;
        break;
    default:
        std::cout << "Unsupported baud rate" << std::endl;
        A010_config.baud=0;
        A010_config.error=1;
        return 1;
    }

    if(ret)
    {
        std::cout << "UART BAUD failed" << std::endl;
        A010_config.error=2;
        return 2;
    }

    A010_Send(uart, A010_CONFIG_BAUD);

    A010_Send(uart, A010_CONFIG_DISP_STOP);
    tcflush(uart, TCIOFLUSH);
    usleep(1000000);
    tcflush(uart, TCIOFLUSH);
    A010_Read(uart);
    A010_Send(uart, "AT\r\n");
    res = A010_Read(uart);
    if (res.find("OK") == std::string::npos) {
        std::cout << "AT BAUD failed! Ready to try again..." << std::endl;
        tcflush(uart, TCIOFLUSH);
        usleep(500000);
        tcflush(uart, TCIOFLUSH);
        A010_Read(uart);
        A010_Send(uart, "AT\r\n");
        res = A010_Read(uart);
        if (res.find("OK") == std::string::npos) {
            std::cout << "AT failed" << std::endl;
            A010_config.error=3;
            return 3;
        }
    }

    for(int i=0;i<(sizeof(configBuf)/sizeof(configBuf[0]));i++)
    {
        if(configBuf[i][0]=='\r' && configBuf[i][1]=='\n')
        {
            break;
        }
        std::cout << "AT command: " << configBuf[i];
        A010_Send(uart, configBuf[i]);
        res = A010_Read(uart);
        if (res.find("OK") == std::string::npos) {
            std::cout << "AT command failed: " << res << std::endl;
            A010_config.error=4;
            return 4;
        }
    }

    A010_config.FPS=A010_VALUE_FPS;
    A010_config.unit=A010_VALUE_UNIT;
    std::cout << "A010 Init Success" << std::endl;

    //A010_TimerInit(uart);
    #if A010_PARSE_DEBUG_FLAG
    A010_FileInit();
    if (!A010_file) 
    {
        fclose(A010_file);
        std::cout << "A010 File Init fail" << std::endl;
        A010_config.error=5;
        return 5;
    } 
    else
    {   
        std::cout << "A010 File Init Success" << std::endl;
    }
    #elif A010_SAVE_WHOLE_FRAME
    A010_FileInit();
    if (!A010_file) 
    {
        fclose(A010_file);
        std::cout << "A010 File Init fail" << std::endl;
        A010_config.error=5;
        return 5;
    } 
    else
    {   
        std::cout << "A010 File Init Success" << std::endl;
    }
    #endif

    #if A010_PARSE_LOG_FLAG
    init_log_file();
    #endif

    A010_GetConfig();

    return 0;
}

int A010_ParseData(const uint8_t * buf,size_t len)
{ 
    #if A010_PARSE_DEBUG_FLAG
    if(A010_file && len > 0) {
        fwrite(buf, 1, len, A010_file);
        fflush(A010_file);  // 确保数据写入磁盘
    }
    #else

    #if !(A010_SAVE_WHOLE_FRAME)
    A010_DataType A010_data;
    #endif
    static std::vector<uint8_t> buffer;  // 持久化缓冲区
    static int skip_counter = 0;        // 跳帧计数器
    static int parse_counter = 0;       // 解析计数器
    static unsigned long long errorFrames = 0;
    static uint8_t last_frame_seq = 0;  // 新增：保存上一帧序号
    static uint32_t currentFrameNum = 0;

    // 将新数据追加到缓冲区
    buffer.insert(buffer.end(), buf, buf + len);
    
    // 循环处理完整帧
    while(buffer.size() >= A010_FRAME_SIZE) {
        bool found = false;
        size_t start_index = 0;
        
        for(; start_index <= buffer.size() - sizeof(A010_HEADER); start_index++) {  // 扩大检测范围
            if(memcmp(&buffer[start_index], A010_HEADER, sizeof(A010_HEADER)) == 0) {  // 使用动态头长度
                // 发现头后检查后续数据是否足够
                if(buffer.size() - start_index >= A010_FRAME_SIZE) {  // 新增检查
                    found = true;
                    break;
                }
                else
                {
                    buffer.erase(buffer.begin(), buffer.begin() + start_index);
                    return 1;  
                }
            }
        }
        
        if(!found) {
            // 计算需要删除的无效数据量（当前buffer长度 - 头长度 + 1）
            size_t delete_count = buffer.size() - sizeof(A010_HEADER) + 1;
            if(delete_count > 0 && buffer.size() > delete_count) {
                buffer.erase(buffer.begin(), buffer.begin() + delete_count);
            }
            return 2;  // 退出当前处理循环
        }

        if(buffer[start_index + 16] == last_frame_seq) {
            buffer.erase(buffer.begin(), buffer.begin() + start_index + A010_FRAME_SIZE);
            continue;
        }

        if(buffer[start_index + 16] < last_frame_seq)
        {
            currentFrameNum++;
        }

        last_frame_seq = buffer[start_index + 16];  // 更新最后接收的帧序号

        // 检查跳帧逻辑
        if(A010_PARSE_DROP > 0 && skip_counter % (A010_PARSE_DROP+1) != 0) {
            buffer.erase(buffer.begin(), buffer.begin() + start_index + A010_FRAME_SIZE);
            skip_counter++;
            continue;
        }

        // 校验帧数据
        uint8_t checksum = 0;
        for(int i = 0; i < A010_FRAME_SIZE - 2; i++) {
            checksum += buffer[start_index + i];
        }
        
        // 检查校验位和停止位
        if(checksum == buffer[start_index + A010_FRAME_SIZE - 2] && 
           buffer[start_index + A010_FRAME_SIZE - 1] == 0xDD)
        {
            #if A010_FRAME_DEBUG_FLAG
            std::cout << "currentFrameNum:" << currentFrameNum << "subFrameNum:" << (uint32_t)buffer[start_index + 16] << std::endl;
            #endif

            #if A010_SAVE_WHOLE_FRAME
            // 保存完整帧数据
            if(A010_file) {
                fwrite(&buffer[start_index], 1, A010_FRAME_SIZE, A010_file);
                fflush(A010_file);
            }

            #if A010_PARSE_LOG_FLAG
            log_info("frame: %d subFrame: %d",currentFrameNum,buffer[start_index + 16]);
            #endif

            #else
            A010_data.frameNum = currentFrameNum;
            A010_data.subFrameNum = buffer[start_index + 16];            
            memcpy(A010_data.data,&buffer[start_index + 20],10000);

            #if A010_PARSE_LOG_FLAG
            log_info("frame: %d subFrame: %d",currentFrameNum,buffer[start_index + 16]);
            #endif

            #endif
            
            parse_counter++;
        }
        else
        {
            errorFrames++;
            std::cout << "errorFrames:" << errorFrames << std::endl;
        }

        // 移除已处理数据
        buffer.erase(buffer.begin(), buffer.begin() + start_index + A010_FRAME_SIZE);
        skip_counter = A010_PARSE_DROP > 0 ? 1 : 0;
    }    
    #endif

    return 0;
}
